package com.ryong21.io;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;

public class PcmRecorder implements Runnable {

	private Logger log = LoggerFactory.getLogger(PcmRecorder.class);
	private volatile boolean isRecording; //录音状态
	private final Object mutex = new Object(); //信号量
	private static final int frequency = 8000; //频率
	private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; //录音编码

	public PcmRecorder() {
		super();
	}
	/**
	 * PcmRecorder  thread is started,  starts executing code.
	 */
	public void run() {
		//PcmWriter Thread
		PcmWriter pcmWriter = new PcmWriter();
		pcmWriter.init();
		Thread writerThread = new Thread (pcmWriter);
		pcmWriter.setRecording(true);
		writerThread.start();
		
		synchronized (mutex) {
			while (!this.isRecording) {
				try {
					mutex.wait();
				} catch (InterruptedException e) {
					throw new IllegalStateException("Wait() interrupted!", e);
				}
			}
		}
		// set Thread priority 设置线程优先权   URGENT 紧急
		android.os.Process
				.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

		int bufferRead = 0;
		//获得读取最小量缓冲区大小
		int bufferSize = AudioRecord.getMinBufferSize(frequency,
				AudioFormat.CHANNEL_IN_MONO, audioEncoding);
		
		short[] tempBuffer = new short[bufferSize];
		//系统录音
		AudioRecord recordInstance = new AudioRecord(
				MediaRecorder.AudioSource.MIC, frequency,
				AudioFormat.CHANNEL_IN_MONO, audioEncoding, bufferSize);
				//MONO 单声道
		recordInstance.startRecording();
		//循环读取录音
		while (this.isRecording) {
			
			bufferRead = recordInstance.read(tempBuffer, 0, bufferSize);
			//操作错误
			if (bufferRead == AudioRecord.ERROR_INVALID_OPERATION) {
				throw new IllegalStateException(
						"read() returned AudioRecord.ERROR_INVALID_OPERATION");
			//值错误
			} else if (bufferRead == AudioRecord.ERROR_BAD_VALUE) {
				throw new IllegalStateException(
						"read() returned AudioRecord.ERROR_BAD_VALUE");

			} 
			//写入数据
			pcmWriter.putData(tempBuffer, bufferRead);
			log.debug("put data done!");
				
		}
		//停止系统录音
		recordInstance.stop();
		pcmWriter.setRecording(false);
	}
	/**
	 * 是否开始录音
	 * @param isRecording
	 */
	public void setRecording(boolean isRecording) {
		synchronized (mutex) {
			this.isRecording = isRecording;
			if (this.isRecording) {
				mutex.notify();
			}
		}
	}
	/**
	 * 返回录音状态
	 * @return
	 */
	public boolean isRecording() {
		synchronized (mutex) {
			return isRecording;
		}
	}
}
